const assert = require("assert");

const addon = require("..");

async function assertRejects(f, ...args) {
  try {
    await f();
  } catch (err) {
    assert.throws(() => {
      throw err;
    }, ...args);

    return;
  }

  assert.throws(() => {}, ...args);
}

describe("Futures", () => {
  describe("Channel", () => {
    it("should be able to await channel result", async () => {
      const sum = await addon.lazy_async_add(
        () => 1,
        () => 2
      );

      assert.strictEqual(sum, 3);
    });

    it("exceptions should be handled", async () => {
      await assertRejects(async () => {
        await addon.lazy_async_add(
          () => 1,
          () => {
            throw new Error("Failed to get Y");
          }
        );
      }, /exception/i);
    });
  });

  describe("JsFuture", () => {
    it("should be able to convert a promise to a future", async () => {
      const nums = new Float64Array([1, 2, 3, 4]);
      const sum = await addon.lazy_async_sum(async () => nums);

      assert.strictEqual(sum, 10);
    });

    it("should catch promise rejection", async () => {
      await assertRejects(async () => {
        await addon.lazy_async_sum(async () => {
          throw new Error("Oh, no!");
        });
      }, /exception/i);
    });
  });
});
